#pragma once
#include "crypto/algorithms/ialgorithm/FAQCipherAlgorithm.h"
#include "crypto/algorithms/ialgorithm/FAQBlockAlgorithm.h"
#include "crypto/algorithms/ialgorithm/FAQKeyAlgorithm.h"
#include "array/Array.hpp"
namespace yzrilyzr_crypto{
	ECLASS(SM4, public FAQCipherAlgorithm, public FAQBlockAlgorithm, public FAQKeyAlgorithm){
	private:
	yzrilyzr_array::IntArray key_r;
	yzrilyzr_array::ByteArray output;
	public:
	SM4();
	u_index getBlockSize()const override;
	/* 加密 */
	yzrilyzr_array::ByteArray encrypt(const yzrilyzr_array::ByteArray & plaintext)override;
	/* 加解密主模块 */
	void sm4Main(const yzrilyzr_array::ByteArray & input, const  yzrilyzr_array::IntArray & key_r, int mod);
	/* 将4个8比特数合并成32比特数 */
	int32_t jointBytes(int8_t byte_0, int8_t byte_1, int8_t byte_2, int8_t byte_3);
	/* S盒变换 */
	int32_t sBox(int32_t box_input);
	/* 将input左移n位 */
	int32_t shift(int32_t input, int32_t n);
	/* 将32比特数拆分成4个8比特数 */
	void splitInt(int32_t n, yzrilyzr_array::ByteArray & output);
	/* 解密 */
	yzrilyzr_array::ByteArray decrypt(const yzrilyzr_array::ByteArray & ciphertext)override;
	void setKey(const FAQKey &key)override;
	void setKey(const yzrilyzr_array::ByteArray & key);
	yzrilyzr_lang::String getAlgorithmName()const override;
	std::shared_ptr<FAQAlgorithm> newInstance()const override;
	};
}